#!/bin/bash
########################################################################
####  Script Name: usl
####  Description: updating tool for smxi scripts
####  version: 2.4.17
####  Date: 2015-02-20
########################################################################
####  Copyright (C) Harald Hope 2007-2014
####
####  This program is free software; you can redistribute it and/or modify it under
####  the terms of the GNU General Public License as published by the Free Software
####  Foundation; either version 3 of the License, or (at your option) any later version.
####
####  This program is distributed in the hope that it will be useful, but WITHOUT
####  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
####  FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
####
####  Get the full text of the GPL here: http://www.gnu.org/licenses/gpl.txt
########################################################################
#### DEFINE:
#### TRUE: -eq 0; == 'true'; function return 0
#### FALSE: -gt 0; == ''; function return > 0
########################################################################
#### VARIABLES
########################################################################

# layout
LINE='- - - - - - - - - - - - - - - - - - - - - - - - - - - - -'

# paths, change these to suite your needs
# first set the master svn, the main target for all others
SMXI_SVN="$HOME/bin/scripts/smxi/svn/trunk/"
# then set the rest
DEV_TOOLS_SVN="${SMXI_SVN}dev-tools/"
INXI_SVN="$HOME/bin/scripts/inxi/svn/trunk/"
KERNEL_SVN="${SMXI_SVN}kernel-stuff/"
RBXI_SVN="$HOME/bin/scripts/rbxi/svn/trunk/"
SGFXI_SVN="$HOME/bin/scripts/sgfxi/svn/trunk/"
STUB_SVN="${SMXI_SVN}smxi-stub/"
SVMI_SVN="$HOME/bin/scripts/svmi/svn/trunk/"

# then set the default svn, no usl startup args given
WORKING_SVN_DIR=$SMXI_SVN

# then set the other stuff
KERNEL_DIR="$HOME/large/kernel-zips/"
RBXI_BZIP="$HOME/bin/scripts/rbxi/rbxi/"
RBXI_DEV="$HOME/bin/scripts/rbxi/dev/"
RBXI_HOME="$HOME/bin/scripts/rbxi/"
RBXI_ZIPS="$HOME/bin/scripts/rbxi/zips/"
SGFXI_DEV="$HOME/bin/scripts/sgfxi/dev/"
SVMI_DEV="$HOME/bin/scripts/svmi/dev/"
SMXI_DEV='/usr/local/bin/'

# scripts/libs
RB_VERSION="${RBXI_SVN}rb-version"
SCRIPT_LIST_SVMI='svmi'
SCRIPT_LIST_SGFXI="sgfxi"
SCRIPT_LIST_INXI='inxi'
SCRIPT_LIST_RBXI='rbxi'
SCRIPT_LIST_MAIN="smxi sm-lib-apt-tools sm-lib-clean-up sm-lib-distro-conversion sm-lib-du-fixes sm-lib-graphics sm-lib-kde4-updater sm-lib-kernel sm-lib-kernel-install sm-lib-misc-tweaks  sm-lib-package-install sm-lib-package-removal sm-lib-warning sm-lib-2006-fixes sm-lib-2007-fixes sm-lib-2008-fixes sm-lib-2008-fixes-s sm-lib-2008-fixes-t sm-lib-2009-fixes sm-lib-2009-fixes-s sm-lib-2009-fixes-t sm-lib-2011-fixes sm-lib-2011-fixes-s sm-lib-2011-fixes-t"
SM_VERSIONS="${SMXI_SVN}sm-versions"
SM_VERSIONS_PREVIOUS="${SMXI_SVN}sm-versions-previous"
# this has to the current live version on smxi.org
SM_VERSIONS_URL='http://smxi.org/sm/sm-versions'

# the primary version number will be manually set.
SM_MAIN_FIRST='8'

B_SKIP_SVN='false'
B_SKIP_ZIP='false'
UPDATE_TYPE='s' # set for default, smxi, or g/i/v

########################################################################
#### FUNCTIONS
########################################################################
# args: $1 error nu; $2 - extra data
error_handler()
{
	local message=''

	case $1 in
		1)
			message='You should not be root to run this script'
			;;
		2)
			message="The directory: $2 does not exist."
			;;
		3)
			message="sed failed for some reason while removing dev flags in file: $2"
			;;
		4)
			message="wget failed to get the file: $2"
			;;
		5)
			message="You used an option that does not exist: $2"
			;;
	esac
	echo $LINE
	echo $message
	echo "Error $1 - Exiting script, please correct the error"
	echo $LINE
	exit $1
}

# args: $1 - "$@"
get_options()
{
	local opt=''

	while getopts :ghirsuvz opt
	do
		case $opt in
			g)
				WORKING_SVN_DIR=$SGFXI_SVN
				UPDATE_TYPE='g'
				B_SKIP_ZIP='true'
				;;
			i)
				WORKING_SVN_DIR=$INXI_SVN
				UPDATE_TYPE='i'
				B_SKIP_ZIP='true'
				;;
			r)
				WORKING_SVN_DIR=$RBXI_SVN
				UPDATE_TYPE='r'
				;;
			u)
				B_SKIP_SVN='true'
				;;
			v)
				WORKING_SVN_DIR=$SVMI_SVN
				UPDATE_TYPE='v'
				B_SKIP_ZIP='true'
				;;
			''|s)
				UPDATE_TYPE='s'
				;;
			z)
				B_SKIP_ZIP='true'
				;;
			h)
				echo "Useage:
-g Update and commit sgfxi svn
-i Update and commit inxi svn
-r Update and commit rbxi svn
-u Update only, skip svn commit
-s (or null, no args) Update and commit smxi svn.
   Will get inxi, sgfxi, and svmi version numbers as well,
   and add those files to the main smxi svn directory for easy
   uploading and handling.
-v Update and commit svmi svn
-z Skip the zip up part
"
				exit 0
				;;
			*)
				error_handler 5 "-$OPTARG"
				;;
		esac
	done
}

start_up_tests()
{
	local startDir=''

	echo $LINE
	echo "Running initial startup tests..."
	# don't want to use root for this script
	if [ "$(whoami)" == 'root' ];then
		error_handler 1
	fi
	
# 	if [[ $UPDATE_TYPE == 'i' ]];then
# 		KERNEL_DIR=''
# 	fi

	# make sure the paths you made are right and exist
	for startDir in $DEV_TOOLS_SVN $INXI_SVN $KERNEL_DIR $KERNEL_SVN $RBXI_BZIP $RBXI_DEV $RBXI_SVN $SMXI_DEV $SGFXI_DEV $SGFXI_SVN $SMXI_SVN $STUB_SVN $SVMI_DEV $SVMI_SVN
	do
		if [ ! -d "$startDir" ];then
			error_handler 2 $startDir
		fi
	done
	echo "Start up tests: passed"
}

make_versions_file()
{
	if [ "$UPDATE_TYPE" == 'r' ];then
		if [ -f $RB_VERSION ];then
			rm -f $RB_VERSION
		fi
		# create the master working file
		touch $RB_VERSION
	else
		if [ -f $SM_VERSIONS ];then
			rm -f $SM_VERSIONS
		fi

		# this ensures that we're working with the true last version, not an off version
		# this is important to have in order to always be using the latest live versions file
		wget -O $SM_VERSIONS_PREVIOUS $SM_VERSIONS_URL || error_handler 4 $SM_VERSIONS_PREVIOUS
		if [ "$?" -gt 0 ];then
			error_handler 4 $SM_VERSIONS_URL
		fi
		# create the master working file
		touch $SM_VERSIONS
	fi
}

# make sure to turn to false all dev flags
clean_dev_flags()
{
	local script='' scripts='smxi sgfxi svmi'
	local isRestart=''
	local isDev=''

	echo "Cleaning dev flags up now..."
	cd $SMXI_SVN
	for script in $scripts
	do
		isRestart=$( grep -i "^SKIP_RESTART='true'" $script )
		isDev=$( grep -i "^DEV_FLAG='true'" $script )

		# just a small fix to make the files not update unless they need to
		if [ -n "$isRestart" -o -n "$isDev" ];then
			# important! only reset where line begins with variable name
			sed -i -e "s/^SKIP_RESTART=.*/SKIP_RESTART=''/" -e "s/^DEV_FLAG=.*/DEV_FLAG=''/" $SMXI_SVN$script || error_handler 3 $script
		fi
	done
}

# this is for those times I forget to clean the -T flag data
clean_gfx_test_data()
{
	local svnGfx="${SMXI_SVN}sgfxi"
	local setTestDataStart=$( grep -n '^set_test_data()' $svnGfx | cut -d ':' -f 1 )
	# start 5 lines below
	setTestDataStart=$(( $setTestDataStart + 6 ))
	echo "Cleaning gfx test data, start line: $setTestDataStart..."
	# add # before any line in the function starting with space
	# remember to search for ' fi', otherwise something like 'specific' triggers it
	sed -i ''${setTestDataStart}',/[[:space:]]fi/ s/^[[:space:]].*/#&/' $svnGfx
}

# trigger update_sm_data
main_updater()
{
	echo $LINE

	if [ "$UPDATE_TYPE" == 'r' ];then
		process_rbxi
	else
		update_sm_data "$SCRIPT_LIST_MAIN" "$SMXI_DEV"
		update_sm_data "$SCRIPT_LIST_SGFXI" "$SGFXI_DEV"
		update_sm_data "$SCRIPT_LIST_SVMI" "$SVMI_DEV"
		update_sm_data "$SCRIPT_LIST_INXI" "$INXI_SVN"
		update_sm_data "$SCRIPT_LIST_RBXI" "$RBXI_SVN"
		update_kernel_installers
		update_other_components
		clean_dev_flags
		clean_gfx_test_data
		finalize_sm_versions
	fi

}

# args: $1 - which data set to update; $2 - data dir
update_sm_data()
{
	local script='' localVersion='' localDate=''

	echo "Updating $2 group now"

	for script in $1
	do
		localVersion=$( grep -im 1 -o -G "version:\ [0-9].[0-9]*.[0-9]*" $2$script | grep -o -G "[0-9].[0-9]*.[0-9]*" )
		# weird: [A-Za-z0-9,\ -] works but [A-Za-z0-9,-\ ] only returns the first number in 2013-10-14
		localDate=$( grep -im 1 -o -G "Date:[\ ]*[A-Za-z0-9,\ -]*" $2$script | cut -f 2-4 -d ' ' )
		echo $script'='$localVersion':'$localDate >> $SM_VERSIONS

		# echo "copy $script to ${SMXI_SVN}$script"
		echo "$script=$localVersion:$localDate"
		cp -f --preserve=timestamps $2$script $SMXI_SVN$script

		# working sgfxi/svmi will often have testing data, don't want to comment out
		# that each update
		case $2 in
			$SGFXI_DEV)
				cp -f --preserve=timestamps $2$script $SGFXI_SVN$script
				;;
			$SVMI_DEV)
				cp -f --preserve=timestamps $2$script $SVMI_SVN$script
				;;
		esac
	done
}

# the basic idea here is simple: for every increment in any script component
# 1st, 2nd, 3rd, increment the overall smxi equivalent number by 1
# for manual primary 1st update, just set 2/3 to 0 and set new date
construct_smxi_version_number()
{
	local script='' incrementFirst='' incrementSecond='' incrementThird=''
	local smMainVersion=$( grep 'sm-main-version=' $SM_VERSIONS_PREVIOUS | cut -d '=' -f 2 | cut -d ':' -f 1 )
	local smMainDate=$( grep 'sm-main-version=' $SM_VERSIONS_PREVIOUS | cut -d '=' -f 2 | cut -d ':' -f 2 )
	local smMainFirst=$( cut -d '.' -f 1 <<< $smMainVersion )
	local smMainSecond=$( cut -d '.' -f 2 <<< $smMainVersion )
	local smMainThird=$( cut -d '.' -f 3 <<< $smMainVersion )
	local smOld='' smNew=''
	local smOldOne='' smNewOne='' smOldTwo='' smNewTwo='' smOldThird='' smNewThird=''

	for script in $SCRIPT_LIST_MAIN
	do
		# get the two values, old and new
		smOld=$( grep "$script=" $SM_VERSIONS_PREVIOUS |cut -d '=' -f 2 | cut -d ':' -f 1 )
		if [ -n "$smOld" ];then
			smOldOne=$( cut -d '.' -f 1 <<< $smOld )
			smOldTwo=$( cut -d '.' -f 2 <<< $smOld )
			smOldThird=$( cut -d '.' -f 3 <<< $smOld )
		# handles case of new smxi files
		else
			smOldOne=0
			smOldTwo=0
			smOldThird=0
		fi
		smNew=$( grep "$script=" $SM_VERSIONS |cut -d '=' -f 2 | cut -d ':' -f 1 )
		smNewOne=$( cut -d '.' -f 1 <<< $smNew )
		smNewTwo=$( cut -d '.' -f 2 <<< $smNew )
		smNewThird=$( cut -d '.' -f 3 <<< $smNew )

		# second number increments occur with change in primary first or second number
		if [ "$smNewOne" -gt "$smOldOne" -o "$smNewTwo" -gt "$smOldTwo" ];then
			incrementSecond='true'
		fi
		# and third number increments occur only with third number differences
		if [ "$smNewThird" -gt "$smOldThird" ];then
			incrementThird='true'
		fi
	done
	if [ "$1" == 'debugger' ];then
		echo "first: $SM_MAIN_FIRST main: $smMainFirst"
		echo "second: main: $smMainSecond"
		echo "third: main: $smMainThird"
	fi
	# first strip off leading zeros to avoid printf error, and make sure to add back in 0
	# if it was a 0 to start with
	# http://www.askdavetaylor.com/how_do_i_strip_leading_zeroes_for_math_in_a_shell_script.html
	smMainSecond=$( sed 's/^0*//' <<< $smMainSecond | awk '{print $1 + 0}' )
	smMainThird=$( sed 's/^0*//' <<< $smMainThird | awk '{print $1 + 0}' )

	# if manual primary version update, just reset 2/3 to 0
	if [ "$SM_MAIN_FIRST" -gt "$smMainFirst" ];then
		smMainFirst=$SM_MAIN_FIRST
		smMainSecond=0
		smMainThird=0
		incrementFirst='true'
	# then update 2nd/3rd if needed
	elif [ "$incrementSecond" == 'true' ];then
		smMainSecond=$(( $smMainSecond + 1 ))
		smMainThird=0
	elif [ "$incrementThird" == 'true' ];then
		smMainThird=$(( $smMainThird + 1 ))
	fi
	# then, if changed, update main date as well
	if [ "$incrementFirst" == 'true' -o "$incrementSecond" == 'true' -o "$incrementThird" == 'true' ];then
		smMainDate=$( date "+%Y-%m-%d" )
	fi
	# process the numbers to make them nice and neat again for output

	smMainSecond=$( printf %02d $smMainSecond )
	smMainThird=$( printf %02d $smMainThird )
	# then print it out to function
	echo "$smMainFirst.$smMainSecond.$smMainThird:$smMainDate"
}

process_rbxi()
{
	cd $RBXI_HOME

	local localVersion='' localDate=''

	echo "Copying rbxi files to bzip and svn"
	cp -f --preserve=timestamps ${RBXI_DEV}rbxi $RBXI_SVN
	cp -f --preserve=timestamps ${RBXI_DEV}rbxi $RBXI_BZIP
	cp -f --preserve=timestamps ${RBXI_DEV}rbxi-data/readme-rbxi.htm ${RBXI_SVN}rbxi-data
	# send excludes
	cp -f --preserve=timestamps ${RBXI_SVN}rbxi-data/excludes* ${RBXI_BZIP}rbxi-data
	# send values/readme
	cp -f --preserve=timestamps ${RBXI_SVN}rbxi-data/rbxi-values ${RBXI_BZIP}rbxi-data
	cp -f --preserve=timestamps ${RBXI_SVN}rbxi-data/readme-rbxi.htm ${RBXI_BZIP}rbxi-data

	local localVersion=$( grep -im 1 -o -G "Version:\ [0-9].[0-9]*.[0-9]*" rbxi/rbxi  | grep -o -G "[0-9].[0-9]*.[0-9]*" )
	local localDate=$( grep -im 1 -o -G "Date:\ [A-Za-z0-9-]*" rbxi/rbxi | cut -f 2-4 -d ' ' )

	echo "rbxi=$localVersion:$localDate" >> $RB_VERSION

	# all files are copied to rbxi/rbxi so tar it
	echo "rbxi data is: $localVersion:$localDate"
	echo "Tar/bzipping now..."
	cd rbxi
	tar vcjf rbxi.tar.bz2 rbxi*
	echo "Moving to: $RBXI_ZIPS"
	mv rbxi.tar.bz2 $RBXI_ZIPS
	echo "Creating backup bzip file now and copying bz2 to svn/trunk..."
	cp -f ${RBXI_ZIPS}rbxi.tar.bz2 ${RBXI_ZIPS}rbxi-$localVersion.tar.bz2
	cp -f ${RBXI_ZIPS}rbxi.tar.bz2 ${RBXI_SVN}rbxi.tar.bz2
	echo "Done with rbxi specific tasks now."
	echo "Remember to upload rbxi/dev/rb-version and rbxi to the remote rb directory"
	echo "on server!!! And the bz2 file."
}
#construct_smxi_version_number;exit

# add closing steps for sm_versions file
finalize_sm_versions()
{
	local smxiVersion=$( construct_smxi_version_number )
	# construct_smxi_version_number
	echo "smxi version number is:"
	construct_smxi_version_number 'debugger'

	echo "Finalizing $SM_VERSIONS now..."
	echo "sm-main-version=$smxiVersion" >> $SM_VERSIONS
	echo >> $SM_VERSIONS
	echo '###**EOF**###' >> $SM_VERSIONS
	# add the versions file to the svn too
	# cp -f --preserve=timestamps $SM_VERSIONS $SMXI_SVN
}

# extra scripts used in smxi, kernel installers for zipped kernels
update_kernel_installers()
{
	local kernelInstaller='install-kernel.sh'

	# update kernel installers if needed
	# note needed anymore, it's a sym link now
	# cp -f ${KERNEL_DIR}kernel-installer/$kernelInstaller $KERNEL_SVN$kernelInstaller
}

# developer scripts for creating smxi
update_other_components()
{
	#cp -f ${DEV_TOOLS_DIR}dsl ${KERNEL_SVN}dsl
	# cp -f ${DEV_TOOLS_DIR}smxi-stub ${STUB_SVN}smxi-stub
	#cp -f ${DEV_TOOLS_DIR}usl ${DEV_TOOLS_SVN}usl
	#cp -f ${DEV_TOOLS_DIR}zsl ${DEV_TOOLS_SVN}zsl
	:
}

# if you have write access to svn, this last step will update svn
update_svn_data()
{
	local response='' response2=''

	echo $LINE
	echo "Please enter the svn commit message:"
	read response

	echo "You entered this:"
	echo $LINE
	echo "$response"
	echo $LINE
	echo "Is this correct (y/n)"
	read response2

	case $response2 in
		y|Y)
			echo "Ok, committing it now"
			commit_to_svn "$response"
			;;
		*)
			echo "Ok, let's try it again..."
			update_svn_data
			;;
	esac
}

# args: $1 - message for commit
commit_to_svn()
{
	svn commit $WORKING_SVN_DIR$svnWild
}

zip_it_up()
{
	if [ "$UPDATE_TYPE" != 'r' -a "$UPDATE_TYPE" != 'i' ];then
		cd $HOME
		su -c "${DEV_TOOLS_SVN}zsl"
	fi
}

finish_it_up()
{
	echo $LINE
	echo "OK, all finished. Remember to upload via ftp the changes to make it live."
}

########################################################################
#### EXECUTE
########################################################################
get_options "$@"
start_up_tests
make_versions_file
main_updater
# comment this out if you do not have svn write access
if [ "$B_SKIP_SVN" == 'false' ];then
	commit_to_svn
	#update_svn_data
fi
if [ "$B_SKIP_ZIP" == 'false' ];then
	zip_it_up
fi
finish_it_up
exit 0
